define(function(){
	// checkbox
	/*
	var myDatepicker=new Datepicker({
		inputDom:this,
		DateDefault:$.newDate(),
		DateNow:$.newDate(),
		weekStartDay:1,
		canlendarNum:2,
		valueType:$this.attr('data-valuetype') || 'single',
		min:$this.attr('data-datemin'),
		max:$this.attr('data-datemax')
	});
	*/
	var Datepicker=function (config){
		var datepicker=this;
		datepicker.$dom=$('<div class="datepicker"></div>')

		datepicker.dayBoxWidth=36;
		datepicker.dayBoxHeight=32;


		datepicker.inputDom=config.inputDom;
		datepicker.$inputDom=$(datepicker.inputDom);
		datepicker.weekStartDay=config.weekStartDay || 0;//每周起始星期


		datepicker.rangeReset=false;



		function configDataInit(keyName){
			if(config && config[keyName]!==undefined && typeof config[keyName]!=='object'){
				config[keyName]=$.newDate(config[keyName]);
			}
		}
		configDataInit('nowDate');
		configDataInit('defDate');
		configDataInit('minDate');
		configDataInit('maxDate');
		datepicker.dateData={
			today:config.nowDate || $.newDate(),//今天
			viewdate:config.defDate || config.nowDate || $.newDate()//查看日期
		}
		if(config.minDate){
			datepicker.dateData.minDateTime=config.minDate.getTime();
		}else{
			datepicker.dateData.minDateTime=false;
		}
		if(config.maxDate){
			datepicker.dateData.maxDateTime=config.maxDate.getTime();
		}else{
			datepicker.dateData.maxDateTime=false;
		}


		datepicker.canlendarNum=config.canlendarNum || 1;
		datepicker.valueType=config.valueType || 'single';


		datepicker.value=[];

		datepicker.inputDomValue=(function(){
			var myValueArr=[];
			var inputValue=$(datepicker.inputDom).value();
			if(inputValue && inputValue!='0'){
				var inputDomValueArr=inputValue.split(',');
				$.each(inputValue.split(','), function(i,v) {
					myValueArr.push($.newDate(v).getTime())
				});
			}
			return myValueArr;
		})();
		if(datepicker.valueType!=='range'){
			datepicker.value=datepicker.inputDomValue;
		}



		function CanlendarTitle(myCanlendar){
			var canlendarTitle=this;
			canlendarTitle.$dom=$('<div class="canlendarTitle"></div>');
			canlendarTitle.$dateTitle=$('<div class="btn dateTitle"></div>').appendTo(canlendarTitle.$dom);
			canlendarTitle.$fullYearText=$('<span class="fullYear"></span>').appendTo(canlendarTitle.$dateTitle);
			canlendarTitle.$fullYearText.on('click',function(){
				if(myCanlendar.canlendarContent.viewType.now=='year'){
					myCanlendar.canlendarContent.changeViewType('day');
				}else{
					myCanlendar.canlendarContent.changeViewType('year');
				}

			})
			canlendarTitle.$dateTitle.append('-');
			canlendarTitle.$monthText=$('<span class="month"></span>').appendTo(canlendarTitle.$dateTitle);
			canlendarTitle.$monthText.on('click',function(){
				if(myCanlendar.canlendarContent.viewType.now=='month'){
					myCanlendar.canlendarContent.changeViewType('day');
				}else{
					myCanlendar.canlendarContent.changeViewType('month');
				}

			})

			canlendarTitle.$btnPrev=$('<div class="btn prev"></div>').appendTo(canlendarTitle.$dom);
			canlendarTitle.$btnPrev.on('mouseup',function(){
				switch(myCanlendar.canlendarContent.viewType.now){
					case 'day':
						datepicker.dateData.viewdate=datepicker.dateData.viewdate.changeMonth(-1);
						datepicker.canlendarList.change();
						break;
					case 'month':
						datepicker.dateData.viewdate=datepicker.dateData.viewdate.changeMonth(-12);
						datepicker.canlendarList.change();
						break;
					case 'year':
						myCanlendar.canlendarContent.viewType.year.reload(-1);
						break;
				}

			});

			canlendarTitle.$btnNext=$('<div class="btn next"></div>').appendTo(canlendarTitle.$dom);
			canlendarTitle.$btnNext.on('mouseup',function(){
				switch(myCanlendar.canlendarContent.viewType.now){
					case 'day':
						datepicker.dateData.viewdate=datepicker.dateData.viewdate.changeMonth(1);
						datepicker.canlendarList.change();
						break;
					case 'month':
						datepicker.dateData.viewdate=datepicker.dateData.viewdate.changeMonth(12);
						datepicker.canlendarList.change();
						break;
					case 'year':
						myCanlendar.canlendarContent.viewType.year.reload(1);
						break;
				}

			});
			canlendarTitle.change=function(){
				canlendarTitle.$fullYearText.html(myCanlendar.viewDate.getFullYear());
				canlendarTitle.$monthText.html(myCanlendar.viewDate.getMonth()+1);
			}
			canlendarTitle.change();
		}


		function WeekTitleTd(sn,dayTable){
			if(sn>=7){
				sn=sn%7;
			}
			var weekTitleTd=this;
			weekTitleTd.$dom=$('<div class="th">'+('day'+sn).tr('datetime')+'</div>').css({
				width:datepicker.dayBoxWidth
			});
			if(datepicker.valueType=='multiple'){
				weekTitleTd.$dom.on('click',function(){
					for(var i=0,len_i=dayTable.tableArr.length;i<len_i;i++){
						var myTrArr=dayTable.tableArr[i]
						for(var j=0,len_j=myTrArr.length;j<len_j;j++){
							var myTd=myTrArr[j];
							if(myTd.date.getDay()==sn){
								myTd.$dom.click();
							}
						}
					}
				});
			}
		}

		function WeekTitleThead(dayTable){
			var weekTitleThead=this;
			weekTitleThead.$dom=$('<div class="thead"></div>');
			weekTitleThead.tdArr=[];
			for(var i=datepicker.weekStartDay,len=datepicker.weekStartDay+7; i<len; i++){
				weekTitleThead.tdArr[i]=new WeekTitleTd(i,dayTable);
				weekTitleThead.$dom.append(weekTitleThead.tdArr[i].$dom);
			}
		}

		function DayTd(myDate,DateFrom,dayTable){
			var dayTd=this;
			dayTd.date=myDate;
			dayTd.time=myDate.getTime();
			dayTd.disabled=false;
			dayTd.$dom=$('<div class="td"><div class="dayNumber">'+myDate.getDate()+'</div></div>');
			if(myDate.isSameDay(datepicker.dateData.today)){
				dayTd.$dom.addClass('today');
			}
			if(datepicker.value.indexOf(myDate.getTime())>=0){
				dayTd.$dom.addClass('checked');
			}

			if(datepicker.valueType==='range' && datepicker.rangeReset===false){
				if(datepicker.inputDomValue.length>1  && dayTd.time>=datepicker.inputDomValue[0] && dayTd.time <= datepicker.inputDomValue[1] ){
					dayTd.$dom.addClass('inRange');
				}

			}

			if((datepicker.dateData.maxDateTime && dayTd.time>datepicker.dateData.maxDateTime) || (datepicker.dateData.minDateTime && dayTd.time<datepicker.dateData.minDateTime)){
				dayTd.disabled=true;
				dayTd.$dom.addClass('disabled');
			}
			dayTd.$dom.css({
				width:datepicker.dayBoxWidth,
				height:datepicker.dayBoxHeight
			});
			if(myDate.getDate()==1){
				dayTd.$dom.css({
					'margin-left':datepicker.dayBoxWidth*((myDate.getDay()-datepicker.weekStartDay+7)%7)
				});
			};
			function dayTdClicked(){
				if(dayTd.disabled){
					return false;
				}
				var outputValueStrArr=[];
				function singleClick(){
					dayTd.$dom.addClass('checked');
					datepicker.value=[myDate.getDayTime()];
					outputValueStrArr=[new Date(datepicker.value[0]).Format('YYYY-MM-DD')];
					datepicker.inputDom.value=outputValueStrArr[0];
					datepicker.inputDom.setAttribute('data-value',outputValueStrArr[0]);
					$(datepicker.inputDom).change();
					datepicker.datepickerBox.close();
				}
				function rangeClick(){
					if(datepicker.value.length>1){
						datepicker.value=[];
					}
					datepicker.value.push(myDate.getDayTime());
					dayTd.$dom.addClass('checked');
					datepicker.rangeReset=true;
					if(datepicker.value.length>1){
						datepicker.value.sort();
						outputValueStrArr.push(new Date(datepicker.value[0]).Format('YYYY-MM-DD'));
						outputValueStrArr.push(new Date(datepicker.value[1]).Format('YYYY-MM-DD'));
						datepicker.inputDom.value=outputValueStrArr.join('~');
						datepicker.inputDom.setAttribute('data-value',outputValueStrArr.join(','));
						$(datepicker.inputDom).change();
						datepicker.datepickerBox.close();
					}else{
						datepicker.$dom.find('.inRange').removeClass('inRange');
					}
				}
				function multipleClick(){
					var rootValueIndexOfMe=-1;
					if(!dayTd.$dom.hasClass('checked')){
						datepicker.value.push(myDate.getDayTime());
						dayTd.$dom.addClass('checked');
					}else{
						rootValueIndexOfMe=datepicker.value.indexOf(myDate.getDayTime());
						if(rootValueIndexOfMe>=0){
							datepicker.value.splice(rootValueIndexOfMe,1);
							dayTd.$dom.removeClass('checked')
						}
					}
					datepicker.value.sort();
					$.each(datepicker.value, function(i,v) {
						outputValueStrArr.push(new Date(Number(v)).Format('YYYY-MM-DD'))
					});
					datepicker.inputDom.value=outputValueStrArr.join(',\n');
					datepicker.inputDom.setAttribute('data-value',outputValueStrArr.join(','));
					$(datepicker.inputDom).change();
				}
				switch(datepicker.valueType){
					case 'single':
						singleClick();
						break;
					case 'range':
						rangeClick();
						break;
					case 'multiple':
						multipleClick();
						break;
				}
			}
			dayTd.$dom.on('click',function(){
				dayTdClicked();
			})

		}
		function DayTable(myCanlendar){
			var dayTable=this;
			dayTable.$dom=$('<div class="canlendarTable date"></div>');
			dayTable.weekTitleThead=new WeekTitleThead(this);
			dayTable.$dom.append(dayTable.weekTitleThead.$dom);
			dayTable.$dayTbody=$('<div class="tbody"></div>').appendTo(dayTable.$dom);
			dayTable.reload=function(){
				dayTable.tableArr=[];
				dayTable.trSnLast=null;
				dayTable.$dayTbody.html('');
				dayTable.dateFirst=new Date(myCanlendar.viewDate.getFullYear(),myCanlendar.viewDate.getMonth(),1);
				dayTable.dayFirst=dayTable.dateFirst.getDay();
				for(var i=0,len=myCanlendar.viewDate.getMonthDateMax(); i<len; i++){
					var dateSn=i+dayTable.dayFirst-datepicker.weekStartDay;
					var dateRowSn=Math.floor(dateSn/7);
					if(dateRowSn!=dayTable.trSnLast){
						dayTable.tableArr.push([]);
						dayTable.trSnLast=dateRowSn;
					}
					var DateMy=new Date(dayTable.dateFirst.getFullYear(),dayTable.dateFirst.getMonth(),i+1);
					dayTable.tableArr[dayTable.tableArr.length-1].push(new DayTd(DateMy,myCanlendar.viewDate,dayTable));
				}
				for(var i_table=0,len_table=dayTable.tableArr.length;i_table<len_table;i_table++){
					var myTrArr=dayTable.tableArr[i_table];
					var $myTrDom=$('<div class="tr"></div>');
					for(var i_tr=0,len_tr=myTrArr.length;i_tr<len_tr;i_tr++){
						$myTrDom.append(myTrArr[i_tr].$dom);
					}
					dayTable.$dayTbody.append($myTrDom);
				}
			}
			dayTable.reload();
		}
		function MonthTable(myCanlendar){
			var monthTable=this;
			monthTable.$dom=$('<div class="canlendarTable month"></div>');
			monthTable.$monthTbody=$('<div class="tbody"></div>').css({
				width:datepicker.dayBoxWidth*7
			}).appendTo(monthTable.$dom);
			function MonthTd(monthNumber){
				var monthTd=this;
				monthTd.$dom=$('<div class="td"><div class="monthNumber">'+('month'+monthNumber).tr('datetime')+'</div></div>').css({
					width:'25%',
					height:datepicker.dayBoxHeight*2
				}).on('click',function(){
					datepicker.dateData.viewdate=$.newDate(myCanlendar.viewDate.Format('YYYY,')+(monthNumber-myCanlendar.sn)+',1');
					datepicker.canlendarList.change();
					myCanlendar.canlendarContent.changeViewType('day');
				});
			}
			monthTable.reload=function(){
				monthTable.$monthTbody.html('');
				for(var i=0,len=12; i<len; i++){
					var monthTd=new MonthTd(i);
					monthTable.$monthTbody.append(monthTd.$dom);
				}
			}
			monthTable.reload();
		}
		function YearTable(myCanlendar){
			var yearTable=this;
			yearTable.$dom=$('<div class="canlendarTable year"></div>');
			/*yearTable.weekTitleThead=new WeekTitleThead(this);*/
			yearTable.$dom.append('<div class="thead"></div>');
			yearTable.$yearTbody=$('<div class="tbody"></div>').css({
				width:datepicker.dayBoxWidth*7
			}).appendTo(yearTable.$dom);
			function YearTd(fullYearNumber){
				var yearTd=this;
				yearTd.$dom=$('<div class="td"><div class="yearNumber">'+fullYearNumber+'</div></div>').css({
					width:'25%',
					height:datepicker.dayBoxHeight
				}).on('click',function(){
					datepicker.dateData.viewdate=$.newDate(fullYearNumber+datepicker.dateData.viewdate.Format(',N,D'));
					datepicker.canlendarList.change();
					myCanlendar.canlendarContent.changeViewType('day');
				});
			}
			yearTable.reload=function(yearChangeDeviation){
				yearTable.$yearTbody.html('');
				var viewYearNumber=myCanlendar.viewDate.getFullYear();
				if(yearChangeDeviation){
					yearTable.yearFirstNumber+=yearChangeDeviation*20;
				}else{
					yearTable.yearFirstNumber=viewYearNumber-viewYearNumber%20;
				}
				for(var i=yearTable.yearFirstNumber,len=yearTable.yearFirstNumber+20; i<len; i++){
					var yearTd=new YearTd(i);
					yearTable.$yearTbody.append(yearTd.$dom);
				}
			}
			yearTable.reload();
		}

		function CanlendarContent(canlendar){
			var canlendarContent=this;
			canlendarContent.$dom=$('<div class="canlendarContent"></div>');
			canlendarContent.viewType={
				'now':'day',
				'day':new DayTable(canlendar),
				'month':new MonthTable(canlendar),
				'year':new YearTable(canlendar)
			}
			canlendarContent.changeViewType=function(viewType){
				if(viewType){
					canlendarContent.viewType.now=viewType;
				}
				canlendarContent.$dom.children().detach();
				switch(canlendarContent.viewType.now){
					case 'day':
						canlendarContent.viewType.day.reload();
						canlendarContent.$dom.append(canlendarContent.viewType.day.$dom);
						break;
					case 'month':
						//canlendarContent.viewType.month.reload();
						canlendarContent.$dom.append(canlendarContent.viewType.month.$dom);
						break;
					case 'year':
						canlendarContent.viewType.year.reload();
						canlendarContent.$dom.append(canlendarContent.viewType.year.$dom);
						break;
				}
			}
			canlendarContent.changeViewType();
		}

		function Canlendar(myViewDate,sn){
			var canlendar=this;
			canlendar.$dom=$('<div class="canlendar"></div>');
			canlendar.viewDate=myViewDate;
			canlendar.sn=sn;
			canlendar.canlendarTitle=new CanlendarTitle(canlendar);
			canlendar.$dom.append(canlendar.canlendarTitle.$dom);
			canlendar.canlendarContent=new CanlendarContent(canlendar);
			canlendar.canlendarContent.changeViewType();
			canlendar.$dom.append(canlendar.canlendarContent.$dom);
			canlendar.change=function(){
				canlendar.canlendarTitle.change();
				canlendar.canlendarContent.changeViewType();
			}
		}
		function CanlendarList(){
			var canlendarList=this;
			canlendarList.list=[]
			for(var i=0,len=datepicker.canlendarNum;i<len;i++){
				canlendarList.list[i]=new Canlendar(datepicker.dateData.viewdate.changeMonth(i),i);
				datepicker.$dom.append(canlendarList.list[i].$dom);
			}
			datepicker.$dom.css({
				width:(datepicker.dayBoxWidth*7+4*2+1)*datepicker.canlendarNum
			})
			canlendarList.change=function(){
				for(var i=0,len=canlendarList.list.length;i<len;i++){
					var myCanlendar=canlendarList.list[i];
					myCanlendar.viewDate=datepicker.dateData.viewdate.changeMonth(i);
					myCanlendar.change();
				}
			}
		}
		datepicker.canlendarList=new CanlendarList();




		datepicker.datepickerBox=new PopUpBox({
			'type':'dom',
			'style':'transparent',
			'show':true,
			'submitBtnType':false,
			'closeBtn':false,
			'bgShow':false,
			'bgClose':true,
			'titleText':false,
			'content':datepicker.$dom,
			'follow':{
				dom:datepicker.inputDom,
				insert:false,
				direction:'center bottom'
			}
		});
	}
	window.Datepicker=Datepicker;
	return Datepicker;
})
